package game.breeze.screen.actors;

import game.breeze.ani.Animation;
import game.breeze.ani.OnAnimationCompleted;
import game.breeze.astar.AStarNode;
import game.breeze.screen.actors.listener.IMotionListener;

import java.util.Collection;
import java.util.LinkedList;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.utils.Disposable;

public class MotionActor extends Actor implements Disposable {
	public static final int STATUS_STAND = 1;
	public static final int STATUS_MOVE_SELF = 2;
	public static final int STATUS_MOVE = 3;
	public static final int STATUS_CUSTOM = 4;

	// TextureRegion region;
	private com.badlogic.gdx.graphics.g2d.Sprite region;
	private Animation ani;
	private Animation stand;
	private Vector2 point = new Vector2();
	private LinkedList<AStarNode> path = new LinkedList<AStarNode>();
	private int cell;
	private IMotionListener listener;
	public int status = STATUS_STAND;

	public MotionActor(String name, game.breeze.ani.Animation moveAni, game.breeze.ani.Animation stand, int cell) {
		super(name);
		this.ani = moveAni;
		this.stand = stand;
		this.cell = cell;
		width = cell;
		height = cell;
		this.region = new com.badlogic.gdx.graphics.g2d.Sprite(moveAni.getKeyFrame(0));
	}

	public void setListener(IMotionListener lis) {
		listener = lis;
	}

	@Override
	public void draw(SpriteBatch batch, float parentAlpha) {
		batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
		region.setPosition(point.x, point.y);
		region.draw(batch);
	}

	private Animation tempAni;
	private OnAnimationCompleted tempAniLis;
	private int aniMode;
	private float motionX;
	private float motionY;
	private float resetX;
	private float resetY;

	public void playMotion(Animation ani, OnAnimationCompleted lis, int aniMode, float motionX, float motionY) {
		ani.reset();
		this.tempAni = ani;
		this.tempAniLis = lis;
		this.aniMode = aniMode;
		status = STATUS_CUSTOM;
		this.motionX = motionX;
		this.motionY = motionY;
		resetX = point.x;
		resetY = point.y;
	}

	private float updateTime = 0;

	public void update(float delta) {
		updateTime = Math.max(updateTime + delta, 0);

		if (status == STATUS_MOVE_SELF) {
			TextureRegion keyFrame = ani.getKeyFrame(updateTime, game.breeze.ani.Animation.ANIMATION_LOOPING);
			if (ani.isChanged()) {
				region.setRegion(keyFrame);
				AStarNode node = path.getLast();// path.pollLast();

				region.setScale(node.getCol() * cell > point.x ? -1 : 1, 1);

				int dirX = node.getCol() * cell >= point.x ? 1 : -1;
				int dirY = node.getRow() * cell >= point.y ? 1 : -1;

				point.y += dirY * 2;
				point.x += dirX * 2;

				if (dirY == 1 && point.y >= node.getRow() * cell) {
					point.y = node.getRow() * cell;
				} else if (dirY == -1 && point.y <= node.getRow() * cell) {
					point.y = node.getRow() * cell;
				}

				if (dirX == 1 && point.x >= node.getCol() * cell) {
					point.x = node.getCol() * cell;
				} else if (dirX == -1 && point.x <= node.getCol() * cell) {
					point.x = node.getCol() * cell;
				}

				if (point.y == node.getRow() * cell && point.x == node.getCol() * cell) {
					path.removeLast();
				}

				if (listener != null) {
					listener.onPositionChange(this, point);
				}

				if (path.size() == 0) {
					status = STATUS_STAND;
					if (listener != null) {
						listener.onMotionStop(this, point);
					}
				}
			}
		} else if (status == STATUS_STAND) {
			TextureRegion keyFrame = stand.getKeyFrame(updateTime, game.breeze.ani.Animation.ANIMATION_LOOPING);
			region.setRegion(keyFrame);
		} else if (status == STATUS_CUSTOM) {
			if (tempAni.isDone()) {
				// 回复原位置
				setPosition(resetX, resetY);
				// 站立状态
				status = STATUS_STAND;
				// 清除动画
				tempAni = null;
				// 如果需要通知
				if (tempAniLis != null) {
					tempAniLis.onCompleted();
				}
			} else {
				// 播放自定义动画
				TextureRegion keyFrame = tempAni.getKeyFrame(updateTime, aniMode);
				region.setRegion(keyFrame);
				region.setScale(1, 1);
				setPosition(motionX, motionY);
			}
		}
	}

	@Override
	public boolean touchDown(float x, float y, int pointer) {
		return false;
	}

	@Override
	public void touchUp(float x, float y, int pointer) {
		// TODO Auto-generated method stub
	}

	@Override
	public void touchDragged(float x, float y, int pointer) {
		// TODO Auto-generated method stub
	}

	@Override
	public Actor hit(float x, float y) {
		return x > 0 && x < cell && y > 0 && y < cell ? this : null;
	}

	public void setPosition(float x, float y) {
		point.x = x;
		point.y = y;
		this.x = point.x;
		this.y = point.y;
	}

	public Vector2 getPostion() {
		return point;
	}

	public void walk(Collection<AStarNode> path) {
		status = STATUS_MOVE_SELF;
		this.path.clear();
		this.path.addAll(path);
	}

	@Override
	public void dispose() {
		region = null;
		ani = null;
		stand = null;
		point = null;
		path.clear();
		path = null;
	}
}
